PRELOADER

不念过去 不负现在 不畏将来

当前文章 : 《STM32 红外线实验》

12/4/2018 —— 

STM32 红外线实验

项目说明

红外线是一种不可见光,因此不像其他的无线信号一样可以穿墙,也因此不会干扰其他相同的红外设备。红外线通信是一种非常方便的无线通信协议。使用红外接收头与STM32连接就可以很容易的实现对STM32的无线控制。
使用红外接收头对发送出来的红外信号进行分析处理,之后将叛变出来的0,1数据传送到STM32单片机,以便执行控制。

知识点

  • 1、红外光的发光源实在是太多了。太阳光是其中最强的一个光源,其它的有诸如:白
    炽灯、蜡烛、热系统中心(如散热器件),甚至我们的身体。实际上,只要有发热的物体,都会发出红外光。调制是我们使需要的信号区别于噪音方法。通过调制我们可以使红外光以特定的频率闪烁。红外接收器会适配这个频率,其它的噪音信号都将被忽略。
  • 2、红外通信的协议有很多种。这个实验使用的是NEC协议。这个协议的采用PWM的方法进行调制,利用脉冲宽度来表示0和1。
  • 3、NEC 遥控指令的数据格式为:同步码头、地址码、地址反码、控制码、控制反码。同步码由一个9ms的低电平和一个4.5ms的高电平组成,地址码、地址反码、控制码、控制反码均是 8 位数据格式。按照低位在前,高位在后的顺序发送。采用反码是为了增加传输的可靠性(可用于校验)。因此,每帧的数据为32位,包括地址码,地址反码,控制码,控制反码。反码可用于解码时进行校验比对。
  • 4、NEC码的位定义:一个脉冲对应560us的连续载波,一个逻辑1传输需要2.25ms(560us 脉冲+1680us 低电平),一个逻辑0的传输需要1.125ms(560us脉冲+560us低电平)。而遥控接收头在收到脉冲的时候为低电平,在没有脉冲的时候为高电平,这样, 我们在接收头端收到的信号为:逻辑 1 应该是 560us 低+1680us 高,逻辑 0 应该是 560us 低+560us 高。

部分代码

  • 1、对于红外接收头,首先需要对其所用的GPIO口进行初始化,并且允许GPIO的中断处理。根据NEC的协议对01数据的时序规定,我们可以通过对GPIO高电平持续时间的判断出0和1信号。
//高电平的持续时间,将记录的时间保存在t中返回,每次20us
u8 HW_jssj()
{
    u8 t=0;
    while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_15)==1)//¸ßµçƽ
    {
        t++;
        delay_us(20);

        if(t>=250) return t;//³¬Ê±Òç³ö
    }

    return t;
}

  • 2、在中断函数对信号的种类进行判断
void EXTI15_10_IRQHandler(void)      //红外遥控外部中断
{
    u8 Tim=0,Ok=0,Data,Num=0;

   while(1)
   {
           if(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_15)==1)
        {
             Tim=HW_jssj();//获得此次高电平时间

             if(Tim>=250) break;//不是有用的信号

             if(Tim>=200 && Tim<250)
             {
                 Ok=1;//收到起始信号
             }
             else if(Tim>=60 && Tim<90)
             {
                 Data=1;//收到数据 1
             }
             else if(Tim>=10 && Tim<50)
             {
                 Data=0;//收到数据 0
             }

             if(Ok==1)
             {
                 hw_jsm<<=1;
                hw_jsm+=Data;

                if(Num>=32)
                {
                    hw_jsbz=1;
                      break;
                }
             }

             Num++;
        }
   }

   EXTI_ClearITPendingBit(EXTI_Line15);
}